home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / misc_lib / imalloc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  5.2 KB  |  195 lines

  1. /******************************************************************************
  2. * All mallocs from irit modules should be piped through this allocator.       *
  3. *                                          *
  4. *                     Written by Gershon Elber, April 1933 *
  5. ******************************************************************************/
  6.  
  7. #include <stdio.h>
  8.  
  9. #include <string.h>
  10. #include "irit_sm.h"
  11. #include "imalloc.h"
  12.  
  13. #define OVERWRITE_STAMP_START 1234567890L    /* A long */
  14. #define OVERWRITE_STAMP_END   0xbd         /* A byte */
  15. #define OVERWRITE_STAMP_FREED -50964L        /* A long */
  16. #define FREE_TABLE_SIZE 100000
  17.  
  18. #if defined(AMIGA) && defined(__SASC)
  19. static VoidPtr __far AllocPtrTable[FREE_TABLE_SIZE];
  20. #else
  21. static VoidPtr AllocPtrTable[FREE_TABLE_SIZE];
  22. #endif
  23. static long
  24.     IritDebugSearchPtr = 0;
  25. static int
  26.     AllocNumPtrs = 0,
  27.     IritDebugMalloc = FALSE,
  28.     IritDebugMallocTested = FALSE;
  29.  
  30. static void AllocError(char *Msg, VoidPtr *p);
  31.  
  32. /*****************************************************************************
  33. * My Routine to    allocate dynamic memory. All program requests must call this *
  34. * routine (no direct call to malloc).                         *
  35. *****************************************************************************/
  36. static void AllocError(char *Msg, VoidPtr *p)
  37. {
  38.     char s[128];
  39.  
  40.     sprintf(s, "%s, Ptr = 0x%lx", Msg, (unsigned long) p);
  41.  
  42.     fprintf(stderr, "Memory allocation error, %s\n", s);
  43. }
  44.  
  45. /*****************************************************************************
  46. * Free all allocated object to test for overwritten data.             *
  47. *****************************************************************************/
  48. void IritTestAllDynMemory(int PrintAlloc)
  49. {
  50.     int i;
  51.  
  52.     for (i = 0; i < AllocNumPtrs; i++) {
  53.     if (AllocPtrTable[i] != NULL) {
  54.         unsigned long
  55.         size = *((unsigned long *) AllocPtrTable[i]);
  56.         VoidPtr
  57.         p2 = ((char *) AllocPtrTable[i]) + 8 + size;
  58.  
  59.         if (*((long *) ((char *) AllocPtrTable[i] + 4)) !=
  60.                         OVERWRITE_STAMP_START)
  61.         AllocError("Overwritten start of dynamically allocated memory",
  62.                AllocPtrTable[i]);
  63.         else if (*((unsigned char *) p2) != OVERWRITE_STAMP_END)
  64.         AllocError("Overwritten end of dynamically allocated memory",
  65.                AllocPtrTable[i]);
  66.  
  67.         if (PrintAlloc)
  68.         printf("Allocated 0x%08lx\n", AllocPtrTable[i]);
  69.     }
  70.     }
  71. }
  72.  
  73. /*****************************************************************************
  74. * My Routine to    allocate dynamic memory. All program requests must call this *
  75. * routine (no direct call to malloc). Dies if no memory.             *
  76. *****************************************************************************/
  77. VoidPtr IritMalloc(unsigned size)
  78. {
  79.     VoidPtr p;
  80.     unsigned OldSize;
  81.  
  82.     if (!IritDebugMallocTested) {
  83.         IritDebugMalloc = getenv("IRIT_MALLOC") != NULL;
  84.         IritDebugSearchPtr = getenv("IRIT_MALLOC_PTR") != NULL ?
  85.                     atoi(getenv("IRIT_MALLOC_PTR")) : 0;
  86.     IritDebugMallocTested = TRUE;
  87.     }
  88.  
  89.     if (IritDebugMalloc) {
  90.     IritTestAllDynMemory(0);
  91.  
  92.     OldSize = size;
  93.     size += 16;
  94.     }
  95.  
  96.     if ((p = malloc(size)) != NULL) {
  97.     if (IritDebugMalloc) {
  98.         int i;
  99.         VoidPtr p2;
  100.  
  101.         if (p != NULL && ((long) p) == IritDebugSearchPtr) {
  102.         printf("Pointer 0x%08lx just allocated\n", p);
  103.         }
  104.  
  105.         /* Save allocated pointer so we can search for it when freed. */
  106.         for (i = 0; i < AllocNumPtrs; i++) {
  107.             if (AllocPtrTable[i] == NULL) {
  108.             AllocPtrTable[i] = p;
  109.             break;
  110.         }
  111.         }
  112.  
  113.         if (i >= AllocNumPtrs) {
  114.         if (i < FREE_TABLE_SIZE - 1)
  115.             AllocPtrTable[AllocNumPtrs++] = p;
  116.         else {
  117.             fprintf(stderr, "Allocation table too small.\n");
  118.             exit(1);
  119.         }
  120.         }
  121.  
  122.         *((long *) p) = OldSize;
  123.         *((long *) (((char *) p) + 4)) = OVERWRITE_STAMP_START;
  124.         p = ((char *) p) + 8;
  125.         p2 = ((char *) p) + OldSize;
  126.         *((char *) p2) = (char) OVERWRITE_STAMP_END;
  127.  
  128.         *((char *) p) = 0; /* In case the freed stamp is still there. */
  129.     }
  130.         
  131.     return p;
  132.     }
  133.  
  134.     IritFatalError("Not Enough dynamic memory");
  135.  
  136.     return NULL;                    /* Make warnings silent. */
  137. }
  138.  
  139. /*****************************************************************************
  140. * My Routine to    free dynamic memory. All program requests must call this     *
  141. * routine (no direct call to free).                         *
  142. *****************************************************************************/
  143. void IritFree(VoidPtr p)
  144. {
  145.     if (IritDebugMalloc) {
  146.     int i;
  147.  
  148.     if (*((long *) p) == OVERWRITE_STAMP_FREED)
  149.         AllocError("Trying to free a free object again", p);
  150.  
  151.     if (p == NULL)
  152.         AllocError("Free a NULL pointer", p);
  153.  
  154.     IritTestAllDynMemory(0);
  155.  
  156.     *((long *) p) = OVERWRITE_STAMP_FREED;
  157.     p = ((char *) p) - 8;
  158.  
  159.     /* Compare the freed pointer with the list of allocated ones. */
  160.     for (i = 0; i < AllocNumPtrs; i++) {
  161.         if (AllocPtrTable[i] == p) {
  162.         AllocPtrTable[i] = NULL;
  163.         break;
  164.         }
  165.     }
  166.  
  167.     if (i >= AllocNumPtrs)
  168.         AllocError("Free unallocated pointer", p);
  169.     }
  170.  
  171. #ifdef __DEBUG_TC_MALLOC__
  172.     switch (heapcheck()) {
  173.     case _HEAPCORRUPT:
  174.         AllocError("Heap is corrupted", p);
  175.         break;
  176.     case _BADNODE:
  177.         AllocError("Attempt to free a bogus pointer", p);
  178.         break;
  179.     case _FREEENTRY:
  180.         AllocError("Attempt to free an already freed pointer", p);
  181.         break;
  182.     case _HEAPOK:
  183.     case _HEAPEMPTY:
  184.     case _USEDENTRY:
  185.         break;
  186.     default:
  187.         AllocError("Allocation error", p);
  188.         break;
  189.  
  190.     }
  191. #endif /* __DEBUG_TC_MALLOC__ */
  192.  
  193.     free(p);
  194. }
  195.